﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Order.cs" company="">
//   
// </copyright>
// <summary>
//   The order.
// </summary>
// --------------------------------------------------------------------------------------------------------------------


using System;
using System.Collections.Generic;
using Systemathics.FrameWork;

namespace Systemathics.FrameWork
{
    public class Order : EventArgs, ICloneable
    {
        public Guid Id                          { get; protected set; }
        public Guid InstrumentId                { get; private set; }
        public StaticData StaticData            { get; private set; }
        public Guid StrategyId                  { get; set; }
        public OrderSide Side                   { get; set; }
        public OrderStyle Style                 { get; set; }
        public Decimal TargetPrice              { get; set; }
        public int TargetQuantity               { get; set; }
        public OrderStatus Status               { get; protected set; }
        public Execution LastExecution          { get; protected set; }
        public Decimal ExecutedAveragePrice     { get; protected set; }
        public int TotalExecutedQuantity        { get; protected set; }
        public int RemainingQuantity            { get; protected set; }
        public Decimal PendingPrice             { get; protected set; }
        public int PendingQuantity              { get; protected set; }
        public OrderExtension Ext               { get; set; } 

        #region constructor

        public Order(Guid instrumentId, StaticData staticData, OrderStyle style, OrderSide side, Decimal price, int quantity, Guid strategyId)
        {
            Id = Guid.NewGuid();
            InstrumentId = instrumentId;
            StrategyId = strategyId;
            StaticData = staticData;

            Style = style;
            Side = side;

            TargetPrice = price;
            TargetQuantity = quantity;

            isSent = false;
            isCancelling = false;
            isModifying = false;
            isAcknowledged = false;
            isRejected = false;
            isCancelled = false;
            isModified = false;

            OrderExecutions = new List<Execution>();
            LastExecution = new Execution(Guid.Empty, 0, 0, String.Empty);

            ExecutedAveragePrice = 0;
            TotalExecutedQuantity = 0;

            PendingQuantity = 0;
            CancelRejectionNumber = 0;
            CancelQuantity = 0;

            ModifyRejectedNumber = 0;
        }

        #endregion constructor

        #region New Order status fields

        public string RejectReason { get; protected set; }
        public bool isSent { get; protected set; }
        public DateTime SendTime { get; set; }
        public DateTime AckTime { get; protected set; }
        public DateTime RejectTime { get; protected set; }
        public bool isAcknowledged { get; protected set; }
        public bool isRejected { get; protected set; }

        #endregion New Order status fields

        #region Cancel status fileds
        public bool isCancelling { get; protected set; }
        public bool isCancelled { get; protected set; }
        public int CancelRejectionNumber { get; protected set; }
        public int CancelQuantity { get; protected set; }
        public DateTime CancelTime { get; protected set; }
        public DateTime CancelAckTime { get; protected set; }

        #endregion

        #region Modify status fileds

        public bool isModified { get; protected set; }
        public bool isModifying { get; protected set; }
        public int ModifyRejectedNumber { get; protected set; }
        public DateTime ModifyTime { get; protected set; }
        public DateTime ModifyAckTime { get; protected set; }

        #endregion Modify status fileds

        #region Order Status Properties

        public bool isPending
        {
            get
            {
                // The order has been sent (new, cancel or modify), but no reply from the market
                return (isSent && !isAcknowledged && !isRejected && !isCancelled && (Status != OrderStatus.FILLED)) || isCancelling || isModifying; //&& !isOutReport
            }
        }
        public bool isOpen
        {
            get
            {
                // The order is on the market (still remaining qty) 
                return isAcknowledged && !isRejected && !isCancelled && (Status != OrderStatus.FILLED); // && !isOutReport
            }
        }
        public bool isClosed
        {
            get
            {
                // The order is closed  
                return isRejected || isCancelled || (Status == OrderStatus.FILLED);// || isOutReport
            }
        }

        #endregion Order Status Properties

        #region Executions

        protected readonly List<Execution> OrderExecutions;
        public Execution[] Executions
        {
            get { return OrderExecutions.ToArray(); }
        }

        #endregion Executions

        #region ICloneable Members

        public object Clone()
        {
            return MemberwiseClone();
        }

        #endregion
    }
}